package com.koalacloud.koala.zhaikucloud.util;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.search.Hit;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: GuoYang
 * @Description
 * @create 2022-05-17
 */
@Service
@RequiredArgsConstructor
public class EsDataOperation {

    private final ElasticsearchClient client;

    /**
     * 写入数据
     * @param tClass
     * @return
     * @param <T>
     */
    public <T> String insert(T tClass) {
        try {
//            String id = UUID.randomUUID().toString();
            // 获取T对象属性id值
            Field field = tClass.getClass().getDeclaredField("id");
            field.setAccessible(true);
            String id = field.get(tClass).toString();

            String index = tClass.getClass().getSimpleName().toLowerCase();
            CreateResponse createResponse = client.create(c -> c.index(index).id(id).document(tClass));
//            System.out.println(createResponse.result());
            return createResponse.id();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 批量写入数据
     */
    public <T> void batchInsert(List<T> list) {
        try {
            BulkRequest.Builder br = new BulkRequest.Builder();
            for (T t : list) {
//                String id = UUID.randomUUID().toString();
                // 获取T对象属性id值
                Field field = t.getClass().getDeclaredField("id");
                field.setAccessible(true);
                String id = field.get(t).toString();

                String index = t.getClass().getSimpleName().toLowerCase();
                br.operations(op -> op.index(idx -> idx.index(index).id(id).document(t)));
            }
            BulkResponse result = client.bulk(br.build());
//            System.out.println(result.items().size());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据Id更新数据
     */
    public <T> String upDocId(String docId, T tClass) {
        try {
            String indexName = tClass.getClass().getSimpleName().toLowerCase();
            UpdateRequest updateRequest = UpdateRequest.of(d -> d.index(indexName).id(docId).doc(tClass));
            return client.update(updateRequest, tClass.getClass()).result().toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据Id进行删除
     * @param docId 文档Id
     * @param clazz 对象
     * @param <T>
     */
    public <T> String delDocId(String docId, Class<T> clazz) {
        try {
            String index = clazz.getSimpleName().toLowerCase();
            // 构建请求
//            DeleteRequest deleteRequest = DeleteRequest.of(o -> o.index(index).id(docId));
//            client.delete(deleteRequest);
            DeleteResponse deleteResponse = client.delete(d -> d.index(index).id(docId));
            return deleteResponse.result().toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据查询条件进行删除
     * @param query 查询条件
     * @param clazz 对象
     * @param <T>
     * @throws IOException
     */
    public <T> void delQuery(Query query, Class<T> clazz) throws IOException {
        String index = clazz.getSimpleName().toLowerCase();
        DeleteByQueryRequest de = DeleteByQueryRequest.of(d -> d.index(index).query(query));
        client.deleteByQuery(de);
    }

    /**
     * 根据Id查询
     * @param docId
     * @param clazz
     * @return
     * @param <T>
     * @throws IOException
     */
    public <T> T getById(String docId, Class<T> clazz) {
        try {
            String index = clazz.getSimpleName().toLowerCase();
            GetResponse<T> response = client.get(g -> g.index(index).id(docId), clazz);
            return  response.source();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查询全部数据
     * size:默认10条
     * @param clazz
     * @return
     * @param <T> T.Class
     * @throws IOException
     */
    public <T> List<T> queryAllDocument(Class<T> clazz) {
        try {
            List<T> list = new ArrayList<>();
            String indexName = clazz.getSimpleName().toLowerCase();
            SearchResponse<T> searchResponse = client.search(s -> s.index(indexName)
                            .query(q -> q.matchAll(m -> m))
                    , clazz);
//                    .size(1000), clazz);
            for (Hit<T> hit : searchResponse.hits().hits()) {
                list.add(hit.source());
            }
//            System.out.println(searchResponse.hits().total().value());
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
